package com.zero.logistics.shiro;

import java.util.List;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import com.zero.logistics.pojo.User;
import com.zero.logistics.pojo.UserExample;
import com.zero.logistics.pojo.UserExample.Criteria;
import com.zero.logistics.service.PermissionService;
import com.zero.logistics.service.UserService;

/*
 *	@date:2020年4月3日 上午5:52:17
 *	@author:Zero
 *	@version:Future
 *	@description: 
 *
 */
public class myRealm extends AuthorizingRealm{
	
	@Autowired
	private UserService userService;
	
	@Autowired
	private PermissionService permissionService;
	
	/**
	 * @function 自定义认证方法
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		System.out.println("认证开始了");
		//1.获取token中的认证身份信息, 直接强转成String类型的username
		String username = (String) token.getPrincipal();
		
		//2.通过从token中获取到的username查询用户信息
		UserExample example = new UserExample();
		Criteria criteria = example.createCriteria();
		criteria.andUsernameEqualTo(username);
		List<User> users = userService.selectByExample(example);
		
		//3.根据查询结果返回认证信息
		//3.1 未查询到用户信息, 直接返回null
		if (users.size() == 0) {
			return null;
		}
		
		//3.2 查询到用户信息, 组装SimpleAuthenticationInfo对象后返回
		User user = users.get(0);
		Object principal = user;
		Object hashedCredentials = user.getPassword();
		ByteSource credentialsSalt = ByteSource.Util.bytes(user.getSalt());
		String realmName = this.getName();
		AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(principal, hashedCredentials, credentialsSalt, realmName);
		return authenticationInfo;
	}

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		System.out.println("授权开始了");
		//1.获取当前认证成功的身份
		User user = (User) principals.getPrimaryPrincipal();
		//2.获取当前认证成功的用户的权限字符串，然后转成字符串数组
		String permissionIds = user.getPermissionIds();
		String[] permissionIdsArr = permissionIds.split(",");
		
		//3.通过权限的字符串数组获取到所有权限的集合
		List<String> permissions = permissionService.getExpressionsByPermissionIds(permissionIdsArr);
		System.out.println("当前用户的权限集合：" + permissions);
		
		//4.创建授权信息对象AuthorizationInfo,然后将权限信息放在授权信息对象中并返回
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		authorizationInfo.addStringPermissions(permissions);
		
		//5.将当前用户的角色设置给授权信息对象，便于前端页面的使用
		authorizationInfo.addRole(user.getRolename());
		return authorizationInfo;
	}

}
